package com.tyk.bookstore.back.payment.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tyk.bookstore.back.common.core.model.type.BinVo;
import com.tyk.bookstore.back.common.core.util.ObjUtil;
import com.tyk.bookstore.back.member.model.dto.Member4PaymentDto;
import com.tyk.bookstore.back.member.service.MemberApiService;
import com.tyk.bookstore.back.order.service.OrderApiService;
import com.tyk.bookstore.back.payment.manager.excel.model.PaymentRecordExcelVo;
import com.tyk.bookstore.back.payment.model.entity.PaymentRecordDo;
import com.tyk.bookstore.back.payment.model.query.PaymentRecordAddQuery;
import com.tyk.bookstore.back.payment.model.query.PaymentRecordPageQuery;
import com.tyk.bookstore.back.payment.model.query.PaymentRecordUpdateQuery;
import com.tyk.bookstore.back.payment.model.vo.PaymentRecordPageVo;
import com.tyk.bookstore.back.payment.model.vo.PaymentRecordVo;
import com.tyk.bookstore.back.payment.repository.PaymentRecordRepository;
import com.tyk.bookstore.back.payment.service.PaymentRecordService;
import com.tyk.bookstore.back.payment.util.MapStructPayment;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;


/**
 * @author tyk
 * @description 支付记录
 */
@Service
@RequiredArgsConstructor

public class PaymentRecordServiceImpl implements PaymentRecordService {

    private final PaymentRecordRepository paymentRecordRepository;
    private final MemberApiService memberApiService;
    private final OrderApiService orderApiService;
    private final MapStructPayment mapStructPayment;

    @Override
    public PaymentRecordVo getById(Long id) {
        PaymentRecordDo paymentRecord = paymentRecordRepository.selectById(id);
        return mapStructPayment.toPaymentRecordVo(paymentRecord);
    }

    @Override
    public PaymentRecordPageVo getPage(PaymentRecordPageQuery query) {
        // 分页查询
        Page<PaymentRecordDo> page = new Page<>(query.getPage(), query.getLimit());
        LambdaQueryWrapper<PaymentRecordDo> w = buildPageQueryWrapper(query);
        paymentRecordRepository.selectPage(page, w);
        PaymentRecordPageVo pv = mapStructPayment.toPaymentRecordPageVo(page);
        // 会员信息
        Set<Long> midSet = page.getRecords().stream().map(PaymentRecordDo::getMemberId).collect(Collectors.toSet());
        Map<Long, Member4PaymentDto> mMap = memberApiService
                .getMember4PaymentDtoListByIdSet(midSet)
                .stream().collect(Collectors.toMap(
                        Member4PaymentDto::getId,
                        it -> it
                ));
        // 订单信息
        Set<Long> oidSet = page.getRecords().stream().map(PaymentRecordDo::getOrderId).collect(Collectors.toSet());
        Map<Long, String> oMap = orderApiService
                .getOrderNoListByIdSet(oidSet)
                .stream().collect(Collectors.toMap(
                        BinVo::getId,
                        BinVo::getValue
                ));
        // 补充
        pv.getRecords().forEach(it -> {
            Member4PaymentDto dto = mMap.get(it.getMemberId());
            it.setMemberName(dto.getNickname())
                    .setMemberAccount(dto.getAccount())
                    .setOrderNo(oMap.get(it.getOrderId()));
        });
        // 返回
        return pv;
    }

    private LambdaQueryWrapper<PaymentRecordDo> buildPageQueryWrapper(PaymentRecordPageQuery query) {
        LambdaQueryWrapper<PaymentRecordDo> w = new LambdaQueryWrapper<>();

        // 支付流水号
        w.eq(ObjUtil.notBlank(query.getTradeNo()), PaymentRecordDo::getTradeNo, query.getTradeNo());

        // 第三方流水号
        w.eq(ObjUtil.notBlank(query.getOutTradeNo()), PaymentRecordDo::getOutTradeNo, query.getOutTradeNo());

        // 支付金额
        w.ge(query.getAmountFrom() != null, PaymentRecordDo::getAmount, query.getAmountFrom());
        w.le(query.getAmountTo() != null, PaymentRecordDo::getAmount, query.getAmountTo());

        // 支付方式
        w.eq(query.getPaymentWay() != null, PaymentRecordDo::getPaymentWay, query.getPaymentWay());

        // 支付时间
        w.ge(query.getPaymentTimeFrom() != null, PaymentRecordDo::getPaymentTime, query.getPaymentTimeFrom());
        w.le(query.getPaymentTimeTo() != null, PaymentRecordDo::getPaymentTime, query.getPaymentTimeTo());

        // 会员账号或昵称
        if (ObjUtil.notBlank(query.getMemberKeyword())) {
            List<Long> midSet = memberApiService.getIdListByKw(query.getMemberKeyword());
            w.in(PaymentRecordDo::getMemberId, midSet);
        }

        // 订单编号
        if (ObjUtil.notBlank(query.getOrderNo())) {
            Long orderId = orderApiService.getIdByOrderNo(query.getOrderNo());
            w.eq(PaymentRecordDo::getOrderId, orderId);
        }

        // 支付时间排序
        w.orderBy(true, false, PaymentRecordDo::getPaymentTime);

        return w;
    }

    @Override
    public void add(PaymentRecordAddQuery query) {
        PaymentRecordDo paymentRecord = mapStructPayment.toPaymentRecordDo(query);
        paymentRecordRepository.insert(paymentRecord);
    }

    @Override
    public void updateById(PaymentRecordUpdateQuery query) {
        PaymentRecordDo paymentRecord = mapStructPayment.toPaymentRecordDo(query);
        paymentRecordRepository.updateById(paymentRecord);
    }

    @Override
    public void deleteById(Long id) {
        paymentRecordRepository.deleteById(id);
    }

    @Override
    public void deleteBatchByIdSet(Set<Long> idSet) {
        paymentRecordRepository.deleteBatchIds(idSet);
    }

    @Override
    public List<PaymentRecordExcelVo> getPaymentRecordExcelVoList(PaymentRecordPageQuery query) {
        LambdaQueryWrapper<PaymentRecordDo> w = buildPageQueryWrapper(query);
        List<PaymentRecordDo> doList = paymentRecordRepository.selectList(w);
        return mapStructPayment.toPaymentRecordExcelVoList(doList);
    }

}

